基于 Babelfish 的 T 您所在的位置:网站首页 pgsql 游标 基于 Babelfish 的 T

基于 Babelfish 的 T

2023-05-26 17:47| 来源: 网络整理| 查看: 265

本文是“基于 Babelfish 的 T-SQL 代码开发最佳实践”系列的第二篇,在上一篇中,我们介绍了基于 Babelfish 的 T-SQL 代码开发时,对于不同的对象属性及互操作性的相关指引和最佳实践。在这篇文章中,我们会对其他的一些开发要点和最佳实践进行介绍。

1. 语法与调试

在本系列的首篇中介绍了 Babelfish 的软件架构是使用 hooks 来处理 TDS 连接,关键之处在于它是在 PostgreSQL 上增加了一个 T-SQL 语法解析器来兼容 SQL Server 的行为。虽然到目前为止 Babelfish 的数据类型和语法兼容性越来越高,但还是存在一些不兼容的地方。本节将介绍 T-SQL 代码在 Babelfish 上开发时遇到的最常见的两类语法差异以及 T-SQL 代码的调试方法。

1)运算符

运算符是 T-SQL 代码中经常会使用到的,对于一些包含两个符号的比较运算符,比如 >=, 这两个比较运算符,可以使用等效的>=和 CREATE EXTENSION tds_fdw;

然后您可以在 Babelfish 中使用 SQL Server 相同的存储过程 sp_addlinkedserver 和 sp_addlinkedsrvlogin 完成远程数据源的配置。注意:此功能同样支持将远端的 Babelfish 也当成 TDS 的数据源。添加链接服务器和登陆用户信息的 T-SQL 请参考下面的语句。注意:当前版本的链接服务器创建和使用需要在master 数据库下执行相关语句

USE [master] GO EXEC sp_addlinkedserver @server='?????', --自定义Linked Server name @datasrc='????? ' --需要访问的数据库Endpoint GO EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname = '?????', --已创建的Linked Server name @useself = 'false', @locallogin = NULL , @rmtuser = '?????' , --需访问的SQL Server实例登陆名 @rmtpassword = '?????'; -- 需访问的SQL Server实例登陆密码 GO

Babelfish 中同样提供了系统视图 sys.servers 和 sys.linked_logins 来查询链接服务器的相关信息,注意查询结果中 sys.servers 视图的 data_source 和 sys.linked_logins 视图的 remote_name 两个字段不能为空。

链接服务器创建成功后,可以使用下面的语句查询远端的数据

SELECT * FROM OPENQUERY (Linked_server_name, 'SELECT * FROM database.schema.table')

通过链接服务器,您可以直接使用远程查询来创建本地表

SELECT * into table_name FROM OPENQUERY (Linked_server_name, 'SELECT * FROM database.schema.table')

或将查询到的远程数据插入本地表

insert into table_name SELECT * FROM OPENQUERY (Linked_server_name, 'SELECT * FROM database.schema.table')

在数据迁移到 Babelfish 后,如果想比较两边数据的差异,我们建议您通过链接服务器来做快速比较:创建一张本地表来存储源表中唯一字段的数据,和本地目标表中唯一字段的数据进行比较,找到具体的差异数据。如下图案例所示:包含 1 千万条数据的源表 transdata,在目标库中有 3 条缺失,我们将源表的唯一字段 empno 存储到 babelfish 中的 master.dbo.t1 表中,然后通过一条简单的查询语句就能将具体的数据找到。

除了对 TDS 数据源的支持外,Aurora PostgreSQL 本身也支持使用 oracle_fdw 扩展来访问 Oracle 数据库源,与链接服务器不同的是,您需要通过 PostgreSQL 的连接去创建映射到 Oracle 的外部表并访问。注意:您无法直接通过 Babelfish 连接去调用此外部表。关于此扩展的更多信息,请参考 Aurora PostgreSQL 的使用手册。我们建议您在 T-SQL 开发过程中,根据实际的外部数据的访问需求,选择适当的方式来处理。

3)所有权链

SQL Server 中对象的访问,会保证只有被授予权限的安全主体(Principal)才能访问安全对象(Securable)。当多个数据库对象相互访问时,访问的对象序列称作链(chain),链中的每个节点都是一个数据库对象。当遍历链中的各个节点时,SQL Server 会采用特殊的方式来评估权限,这跟分别访问单个对象时的权限评估方式不同。

所有权链是一种特殊的权限评估方式:只检查链中对象的所有者,如果所有者相同,那么有权限访问该对象。也即是说在所有权链中,SQL Server 完全信任数据库对象的所有者(Owner),不会检查用户是否具有该对象的访问权限,只比较链中相邻的两个对象的所有者是否相同,如果相同,那么就有权限访问该对象;只在所有者不同时,才会执行权限检查。这在数据库管理上非常有用,但也会带来潜在的风险。

假设存在一个存储过程,用于从一个数据表中读取数据,用户被授予对存储过程的执行权限。如果存储过程和表具有相同的所有者,那么不需要被授予对该表的任何权限(甚至被授予拒绝权限),用户都可以访问该数据表。但是,如果存储过程和表具有不同的所有者,那么 SQL Server 必须在允许访问数据之前检查用户在表上的权限。

在 Babelfish 中,SQL Server 所有权链适用于视图,但不适用于存储过程。这意味着必须授予过程对与调用过程相同的所有者拥有的其他对象的显式访问权限。在 SQL Server 中,授予调用者对该过程的 EXECUTE 权限就足以调用同一所有者拥有的其他对象。在 Babelfish 中,还必须向调用者授予对该过程访问的对象的权限。

来看具体的案例,在 SQL Server 和 Babelfish 中,存储过程 P_Test1 和过程中需要访问的表 emp 都是属于管理用户,通过 SQL 语句将存储过程 P_Test1 的执行权限授予用户“user1”,表 emp 不做操作。

GRANT EXEC on P_TEST1 to user1

使用 user1 在 SQL Server 和 Babelfish 中分别执行存储过程,结果显示 Babelfish 不能通过所有权链的方式直接在执行过程中访问表 emp,需要向用户授权访问,而 SQL Sever 则不需要。

鉴于 Babelfish 的所有权链处理方式和 SQL Server 的不同,可能会导致应用运行错误,我们建议您检查类似的 T-SQL 代码,如果需要则授予用户相应的访问权限。

4. 总结

在本篇文章中,我们向您介绍了更多的基于 Babelfish 的 T-SQL 开发最佳实践。您可以使用原有 SQL Server 开发经验,结合这些最佳实践,开发出适应业务需求的应用和 T-SQL 代码。

Babelfish 是一项不断发展的 Aurora PostgreSQL 功能,自它伴随着 Aurora PostgreSQL 13.4 首次推出以来,Babelfish 的每个新版本都添加了可更好地与 T-SQL 功能和行为保持一致的特性和功能,如 Babelfish 的各个版本支持的功能表中所示。为了在使用 Babelfish 时获得最佳效果,我们建议您通过官方手册了解 SQL Server 与最新版本的 Babelfish 支持的 T-SQL 之间目前存在的区别。

本篇作者 唐晓华

亚马逊云科技数据库解决方案技术专家,二十余年数据库行业经验,负责基于亚马逊云计算数据库产品的技术咨询与解决方案工作。专注于云上关系型数据库架构设计、测试、运维、优化及迁移等工作。

张子曼

亚马逊云科技解决方案架构师,负责基于 AWS 云计算方案架构的咨询和设计,在国内推广 AWS 云平台技术和各种解决方案。专注于 Serverless 和数据库等技术方向。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有